\chapter{QSqlDatabase}

QSqlDatabase 类 用于处理数据库的连接

\begin{tabular}{|c|c|}
	\hline
	属性 & 方法 \\
	\hline
	头文件 & \#include <QSqlDatabase>\\      
	\hline
	qmake & QT += sql\\      
	\hline
\end{tabular}


\href{https://doc.qt.io/qt-5/qsqldatabase-members.html}{列出所有的成员，包括继承成员}

\section{公共类型}

\resizebox{\textwidth}{!}{ % Latex表格宽度超出文本宽度
\begin{tabular}{|r|l|}
\hline
返回值 & 函数名 \\
\hline
 & QSqlDatabase(const QSqlDatabase \&other) \\ 
\hline
 & QSqlDatabase()\\
\hline
QSqlDatabase \&	&operator=(const QSqlDatabase \&other)\\
\hline
 & ~QSqlDatabase()\\
\hline
void& close()\\
\hline
bool&commit()\\
\hline
QString	&connectOptions() const\\
\hline
QString	&connectionName() const\\
\hline
QString	&databaseName() const\\
\hline
QSqlDriver *&	driver() const\\
\hline
QString	&driverName() const\\
\hline
QSqlQuery&	exec(const QString \&query = QString()) const\\
\hline
QString	&hostName() const\\
\hline
bool	&isOpen() const\\
\hline
bool	&isOpenError() const\\
\hline
bool	&isValid() const\\
\hline
QSqlError&	lastError() const\\
\hline
QSql::NumericalPrecisionPolicy & numericalPrecisionPolicy() const\\
\hline
bool	&open()\\
\hline
bool&	open(const QString \&user, const QString \&password)\\
\hline
QString&	password() const\\
\hline
int	&port() const\\
\hline
QSqlIndex&	primaryIndex(const QString \&tablename) const\\
\hline
QSqlRecord&	record(const QString \&tablename) const\\
\hline
bool	&rollback()\\
\hline
void	&setConnectOptions(const QString \&options = QString())\\
\hline
void	&setDatabaseName(const QString \&name)\\
\hline
void	&setHostName(const QString \&host)\\
\hline
void	& setNumericalPrecisionPolicy(QSql::NumericalPrecisionPolicy    precisionPolicy)\\
\hline
void	&setPassword(const QString \&password)\\
\hline
void	&setPort(int port)\\
\hline
void	&setUserName(const QString \&name)\\
\hline
QStringList	&tables(QSql::TableType type = QSql::Tables) const\\
\hline
bool&	transaction()\\
\hline
QString	&userName() const\\
\hline
\end{tabular}
}

\section{静态公共成员}

\resizebox{\textwidth}{!}{ % Latex表格宽度超出文本宽度
\begin{tabular}{|r|l|}
	\hline
	返回值 & 函数名 \\
	\hline
	QSqlDatabase&	addDatabase(const QString \&type, const QString \&connectionName = QLatin1String(defaultConnection))\\
		\hline
	QSqlDatabase&	addDatabase(QSqlDriver *driver, const QString \&connectionName = QLatin1String(defaultConnection))\\
		\hline
	QSqlDatabase&	cloneDatabase(const QSqlDatabase \&other, const QString \&connectionName)\\
		\hline
	QSqlDatabase&	cloneDatabase(const QString \&other, const QString \&connectionName)\\
		\hline
	QStringList&	connectionNames()\\
		\hline
	bool&	contains(const QString \&connectionName = QLatin1String(defaultConnection))\\
		\hline
	QSqlDatabase&	database(const QString \&connectionName = QLatin1String(defaultConnection), bool open = true)\\
		\hline
	QStringList&	drivers()\\
		\hline
	bool&	isDriverAvailable(const QString \&name)\\
		\hline
	void&	registerSqlDriver(const QString \&name, QSqlDriverCreatorBase *creator)\\
		\hline
	void&	removeDatabase(const QString \&connectionName)\\
	\hline
\end{tabular}
}

\section{受保护的成员函数}

\begin{tabular}{|r|l|}
	\hline
	返回值 & 函数名 \\
	\hline
	&QSqlDatabase(QSqlDriver \emph{*driver})\\
	\hline
	&QSqlDatabase(const QString \emph{\&type})\\
	\hline
\end{tabular}


\section{详细的介绍}

QSqlDatabase 类提供接口用于数据库的连接 。一个 QSqlDatabase 实例对象表示连接。 这个连接提供 数据库 所需要的 驱动，这个驱动来自于 QSqlDriver。 换而言之，您可以实现自己的数据库驱动，通过继承 QSqlDriver。查看\href{https://doc.qt.io/qt-5/sql-driver.html#how-to-write-your-own-database-driver}{如何实现自己的数据库驱动}来获取更多的信息。

通过调用一个静态的 addDatabase()函数，来创建一个连接（即：实例化一个QSqlDatabase类）,并且可以指定驱动或者驱动类型去使用（依赖于数据库的类型 ）和 一个连接的名称。 一个连接是通过它自已的名称，而不是通过数据库的名称去连接的。对于一个数据库您可以有多个连接。QSqlDatabase 也支持默认连接，您可以不 传递连接名参数给 addDatabase() 来创建 它。随后，这个默认连接假定您 在调用任何静态函数情况下，而不去指定连接名称。 下面的一段代码片段展示了 如何去创建 和打开一个默认连接，去连接 PostgreSQL 数据库：

\begin{cppcode}
QSqlDatabase db = QSqlDatabase::database();
\end{cppcode}

QSqlDatabase是一个值类。通过一个 QSqlDatabase 实例对数据库连接所做的操作将影响表示相同连接的其他 QSqlDatabase 实例。 使用 cloneDatabase() 在基于已存在数据库的连接 来 创建 独立的数据库的连接。

\begin{warning}
强烈建议不要将QSqlDatabase的拷贝作为类成员，因为这将阻止关闭时正确清理实例。 如果需要访问已经存在QSqlDatabase，应该使用database()访问。如果您选择使用作为成员变量的QSqlDatabase，则需要在删除QCoreApplication实例之前删除它，否则可能会导致未定义的行为。
\end{warning}

如果您想创建多个数据库连接，可以调用 addDatabase(), 并且给一个独一无二的参数(即：连接名称)。使用 带有连接名的database() 函数，来获取该连接。使用 带有连接名的removeDatabase() 函数，来删除 一个连接。如果尝试删除由其他QSqlDatabase对象引用的连接，QSqlDatabase将输出警告。可以使用 \href{https://github.com/QtDocumentCN/QtDocumentCN/blob/master/Src/S/QSqlDatabase/QSqlDatabase.md#static-bool-qsqldatabasecontainsconst-qstring-connectionname--qlatin1stringdefaultconnection}{contains()}查看给定的连接名是否在连接列表中。


\begin{tabular}{|c|c|}
	\hline	
		& 一些实用的方法\\
	\hline
	\href{https://github.com/QtDocumentCN/QtDocumentCN/blob/master/Src/S/QSqlDatabase/QSqlDatabase.md#qstringlist-qsqldatabasetablesqsqltabletype-type--qsqltables-const}{tables()} &	返回 数据表的列表\\
		\hline
	\href{https://github.com/QtDocumentCN/QtDocumentCN/blob/master/Src/S/QSqlDatabase/QSqlDatabase.md#qsqlindex-qsqldatabaseprimaryindexconst-qstring-tablename-const}{primaryIndex()} &返回数据表的主索引\\
		\hline
	\href{URL}{record()} &	返回数据表字段的元信息\\
		\hline
	\href{URL}{transaction()} &开始一个事务\\
		\hline
	\href{URL}{commit()}&	保存并完成一个事务\\
		\hline
	\href{URL}{rollback()}&	取消一个事务\\
		\hline
	\href{URL}{hasFeature()}&	检查驱动程序是否支持事务\\
		\hline
	\href{URL}{lastError()}	&返回有关上一个错误的信息\\
		\hline
	\href{URL}{drivers()}	&返回可用的数据库驱动名称\\
		\hline
	\href{URL}{isDriverAvailable()}	&检查特定驱动程序是否可用\\
		\hline
	\href{URL}{registerSqlDriver()}	&注册自定义驱动程序\\
		\hline
\end{tabular}

\begin{notice}
QSqlDatabase::exec() 方法已经被弃用。请使用 QSqlQuery::exec()
\end{notice}

\begin{notice}
使用事务时，必须在创建查询之前启动事务。
\end{notice}

\section{成员函数文档}

[protected] QSqlDatabase::QSqlDatabase(QSqlDriver *driver)

这是一个重载函数

使用给定驱动程序来创建连接

[protected] QSqlDatabase::QSqlDatabase(const \href{https://github.com/QtDocumentCN/QtDocumentCN/blob/master/Src/S/QString/QString.md}{QString} \&type)

这是一个重载函数

通过引用所给的数据库驱动类型来创建一个连接。如果不给定 数据库驱动类型 ，那么这个数据库连接将会没有什么作用。

当前可用的驱动类型：

\begin{tabular}{|r|l|}
	\hline	
	驱动类别& 介绍\\
	\hline
	QDB2&	IBM DB2\\
		\hline
	QIBASE	&Borland InterBase 驱动\\
		\hline
	QMYSQL	&MySQL 驱动\\
		\hline
	QOCI	&Oracle 调用的接口驱动\\
		\hline
	QODBC	&ODBC 驱动 (包含 Microsoft SQL Server)\\
		\hline
	QPSQL	&PostgreSQL 驱动\\
		\hline
	QSQLITE	&SQLite 第三版本 或者 以上\\
		\hline
	QSQLITE2&	SQLite 第二版本\\
		\hline
	QTDS	&Sybase Adaptive Server\\
	\hline
\end{tabular}

其他第三方驱动程序，包括自己自定义的驱动程序，都可以动态加载。

\begin{seeAlso}
\href{https://doc.qt.io/qt-5/sql-driver.html}{SQL Database Drivers}, \href{https://github.com/QtDocumentCN/QtDocumentCN/blob/master/Src/S/QSqlDatabase/QSqlDatabase.md#static-void-qsqldatabaseregistersqldriverconst-qstring-name-qsqldrivercreatorbase-creator}{registerSqlDriver()} 和 \href{https://github.com/QtDocumentCN/QtDocumentCN/blob/master/Src/S/QSqlDatabase/QSqlDatabase.md#static-qstringlist-qsqldatabasedrivers}{drivers()}。
\end{seeAlso}


QSqlDatabase::QSqlDatabase(const QSqlDatabase \emph{\&other})

创建一个其它的副本

QSqlDatabase::QSqlDatabase()

创建一个 无效的 QSqlDatabase 空对象。
使用\href{https://github.com/QtDocumentCN/QtDocumentCN/blob/master/Src/S/QSqlDatabase/QSqlDatabase.md#static-qsqldatabase-qsqldatabaseadddatabaseconst-qstring-type-const-qstring-connectionname--qlatin1stringdefaultconnection}{addDatabase()},  \href{https://github.com/QtDocumentCN/QtDocumentCN/blob/master/Src/S/QSqlDatabase/QSqlDatabase.md#static-void-qsqldatabaseremovedatabaseconst-qstring-connectionname}{removeDatabase()} 和\href{https://github.com/QtDocumentCN/QtDocumentCN/blob/master/Src/S/QSqlDatabase/QSqlDatabase.md#static-qsqldatabase-qsqldatabasedatabaseconst-qstring-connectionname--qlatin1stringdefaultconnection-bool-open--true}{database()} 来获得一个有效的 QSqlDatabase 对象。

QSqlDatabase \&QSqlDatabase::operator=(const QSqlDatabase \emph{\&other})

给这个对象赋一个其他其他对象的值

QSqlDatabase::$\sim$QSqlDatabase()

销毁这个对象，并且释放所有配置的资源 

\begin{notice}
当最后的连接被销毁，这个折构函数就会暗中的调用 close()函数，去删除这个数据库的其他连接。
\end{notice}

\begin{seeAlso}
\href{https://github.com/QtDocumentCN/QtDocumentCN/blob/master/Src/S/QSqlDatabase/QSqlDatabase.md#void-qsqldatabaseclose}{close()}。
\end{seeAlso}



[static] QSqlDatabase QSqlDatabase::addDatabase(const QString \emph{\&type},const QString \emph{\&connectionName} = QLatin1String(defaultConnection))

使用驱动程序类型和连接名称，将数据库添加到数据库连接列表中。如果存在相同的连接名，那么这个连接将会被删除。

通过引用连接名，来返回一个新的连接。

如果数据库的类别不存在或者没有被加载，那么 isValid()函数将会返回 false

如果我们没有指定连接名参数，那么应用程序就会返回默认连接。 如果我们提供了连接名参数，那么可以使用database(connectionName) 函数来获取该连接。

\begin{warning}
如果您指定了 相同的连接名参数，那么就会替换之前的那个相同的连接。如果您多次调用这个函数而不指定 连接名参数，则默认连接将被替换。
\end{warning}


在使用连接之前，它必须经过初始化。
比如： 调用下面一些或者全部 \href{https://github.com/QtDocumentCN/QtDocumentCN/blob/master/Src/S/QSqlDatabase/QSqlDatabase.md#void-qsqldatabasesetdatabasenameconst-qstring-name}{setDatabaseName()} 、 \href{https://github.com/QtDocumentCN/QtDocumentCN/blob/master/Src/S/QSqlDatabase/QSqlDatabase.md#void-qsqldatabasesetusernameconst-qstring-name}{setUserName()}、 \href{https://github.com/QtDocumentCN/QtDocumentCN/blob/master/Src/S/QSqlDatabase/QSqlDatabase.md#void-qsqldatabasesetpasswordconst-qstring-password}{setPassword()} 、 \href{https://github.com/QtDocumentCN/QtDocumentCN/blob/master/Src/S/QSqlDatabase/QSqlDatabase.md#void-qsqldatabasesethostnameconst-qstring-host}{setHostName()}、 \href{https://github.com/QtDocumentCN/QtDocumentCN/blob/master/Src/S/QSqlDatabase/QSqlDatabase.md#void-qsqldatabasesetportint-port}{setPort()} 和 \href{https://github.com/QtDocumentCN/QtDocumentCN/blob/master/Src/S/QSqlDatabase/QSqlDatabase.md#void-qsqldatabasesetconnectoptionsconst-qstring-options--qstring}{setConnectOptions()}，并最终调用 \href{https://github.com/QtDocumentCN/QtDocumentCN/blob/master/Src/S/QSqlDatabase/QSqlDatabase.md#bool-qsqldatabaseopen}{open()}



\begin{notice}
这个函数是线程安全的
\end{notice}


\begin{seeAlso}
\href{https://github.com/QtDocumentCN/QtDocumentCN/blob/master/Src/S/QSqlDatabase/QSqlDatabase.md#static-qsqldatabase-qsqldatabasedatabaseconst-qstring-connectionname--qlatin1stringdefaultconnection-bool-open--true}{database()}, \href{https://github.com/QtDocumentCN/QtDocumentCN/blob/master/Src/S/QSqlDatabase/QSqlDatabase.md#static-void-qsqldatabaseremovedatabaseconst-qstring-connectionname}{removeDatabase()} 以及 \href{https://doc.qt.io/qt-5/threads-modules.html#threads-and-the-sql-module}{ 线程和SQL 单元}。
\end{seeAlso}


[static] QSqlDatabase QSqlDatabase::addDatabase(QSqlDriver \emph{*driver}, const QString \emph{\&connectionName} = QLatin1String(defaultConnection))

这个重载函数是非常有用的，当您想创建一个带有\href{https://doc.qt.io/qt-5/qsqldriver.html}{驱动} 连接时，您可以实例化它。有可能您想拥有自己的数据库驱动，或者去实例化 Qt自带的驱动。如果您真的想这样做，我非常建议您把驱动的代码导入到您的应用程序中。例如，您可用自已的 QPSQL 驱动来创建一个 PostgreSQL 连接，像下面这样:

\begin{cppcode}
PGconn *con = PQconnectdb("host=server user=bart password=simpson dbname=springfield");
QPSQLDriver *drv = new QPSQLDriver(con);
QSqlDatabase db = QSqlDatabase::addDatabase(drv); // 产生成新的默认连接
QSqlQuery query;
query.exec("SELECT NAME, ID FROM STAFF");	
\end{cppcode}

上面的代码用于设置一个 PostgreSQL 连接和实例化一个 QPSQLDriver 对象。接下来，addDatabase() 被调用产生一个已知的连接，以便于它可以使用 Qt SQL 相关的类。Qt假定您已经打开了数据库连接，当使用连接句柄（或一组句柄）实例化驱动程序时。

\begin{notice}
我们假设qtdir是安装Qt的目录。假定您的PostgreSQL头文件己经包含在搜索路径中，然后这里才能引用所需要的PostgreSQL客户端库和去实例化QPSQLDriver对象。
\end{notice}



请记住，必须将数据库客户端库到您的程序里。确保客户端库在您的链接器的搜索路径中，并且像下面这样添加到您的 .pro 文件里：

\begin{cppcode}
unix:LIBS += -lpq
win32:LIBS += libpqdll.lib
\end{cppcode}

这里介绍了所有驱动支持的方法。只有驱动的构造参数有所不同。列举了一个关于 Qt附带的程序，以及它们的源代码文件，和它们的构造函数参数的列表：

\resizebox{\textwidth}{!}{ % Latex表格宽度超出文本宽度
\begin{tabular}{|l|l|l|l|}
	\hline
	驱动	&类名	& 构造器参数	& 用于导入的文件\\
	\hline
QPSQL	&QPSQLDriver	&PGconn *connection	&qsql\_psql.cpp \\
\hline
QMYSQL	&QMYSQLDriver	&MYSQL *connection	&qsql\_mysql.cpp\\
\hline
QOCI	&QOCIDriver	&OCIEnv *environment, OCISvcCtx *serviceContext	&qsql\_oci.cpp\\
\hline
QODBC	&QODBCDriver	&SQLHANDLE environment, SQLHANDLE connection	&qsql\_odbc.cpp\\
\hline
QDB2	&QDB2	&SQLHANDLE environment, SQLHANDLE connection	&qsql\_db2.cpp\\
\hline
QTDS	&QTDSDriver	&LOGINREC *loginRecord, DBPROCESS *dbProcess, const QString \&hostName	&qsql\_tds.cpp\\
\hline
QSQLITE	&QSQLiteDriver	&sqlite *connection	&qsql\_sqlite.cpp\\
\hline
QIBASE	&QIBaseDriver	&isc\_db\_handle connection	&qsql\_ibase.cpp\\
 
	\hline
\end{tabular}}

当构造用于为内部查询创建新连接的QTDSDriver时，需要主机名（或服务名）。这是为了防止在同时使用多个QSqlQuery对象时发生阻塞。

\begin{warning}
我们假设添加一个存在连接名的连接时，这个新添加的连接将会替换另一个。 
\end{warning}

\begin{warning}
	 SQL框架拥有驱动程序的所有权。它不能被删除。可以使用removeDatabase()，去删除这个连接。 另请参阅drivers()
\end{warning}

[protected] QSqlDatabase QSqlDatabase::cloneDatabase(const QString \&other, const QString \&connectionName)

克隆其他数据库连接并将其存储为connectionName。原始数据库中的所有设置，例如databaseName()、hostName()等，都会被复制。如果其他数据库无效，则不执行任何操作。返回最新被创建的数据库连接。



\begin{warning}
这个新的连接不能被打开。您必须调用 open(),才能使用这个新的连接。
\end{warning}

[static] QSqlDatabase QSqlDatabase::cloneDatabase(const QString \emph{\&other}, const QString \emph{\&connectionName})
这是个重载函数。

克隆其他数据库连接并将其存储为connectionName。原始数据库中的所有设置，例如databaseName()、hostName()等，都会被复制。如果其他数据库无效，则不执行任何操作。返回最新被创建的数据库连接。



\begin{notice}
这个新的连接不能被打开。您必须调用 open(),才能使用这个新的连接。
\end{notice}

当我们在另一个线程克隆这个数据库，这个重载是非常有用的。

qt5.13中引入了这个函数。

void QSqlDatabase::close()

关闭数据库连接，释放获取的所有资源，
并使与数据库一起使用的任何现有QSqlQuery对象无效

这个函数也会影响它的QSqlDatabase对象副本。

\begin{seeAlso}
removeDatabase()
\end{seeAlso}


bool QSqlDatabase::commit()

如果驱动支持事务和一个transaction()已经被启动，
那就可以提交一个事务到这个数据库中。如果这个操作成功，就会返回 true。否则返回 false。

\begin{notice}
对于一些数据库，如果对数据库使用SELECT进行查询操作，
将会提交失败并且返回false。在执行提交之前，使查询处于非活动状态。
\end{notice} 

调用 lastError() 函数获取错误信息。

\begin{seeAlso}
 QSqlQuery::isActive()， QSqlDriver::hasFeature()，和 rollback()。
\end{seeAlso}


QString QSqlDatabase::connectOptions() const

返回用于此连接的连接选项字符串。这个字符串可能是空。


\begin{seeAlso}
setConnectOptions()
\end{seeAlso}

QString QSqlDatabase::connectionName() const

返回连接名，它有可能为空。


\begin{notice}
这个连接名不是 数据库名
\end{notice}

qt4.4 中引入了这个函数。

\begin{seeAlso}
addDatabase()
\end{seeAlso}


[static] QStringList QSqlDatabase::connectionNames()

返回包含所有连接名称的列表。

\begin{notice}
这个函数是线程安全的。
\end{notice} 

\begin{seeAlso}
contains()，database()， 和 线程和SQL模块
\end{seeAlso}

[static] bool QSqlDatabase::contains(const QString \emph{\&connectionName} = QLatin1String(defaultConnection))


如果所给的连接名，包含在所给的数据库连接列表里，那么就返回 true；否则返回 false。

\begin{notice}
这个函数是 线程安全的
\end{notice} 

\begin{seeAlso}
connectionNames(), database() 和 线程和SQL模块。
\end{seeAlso}


[static] QSqlDatabase QSqlDatabase::database(const QString \emph{\&connectionName} = QLatin1String(defaultConnection), bool open = true)

返回一个调用 connectionName 参数的数据库连接。这个数据库连接使用之前，必须已经通过 addDatabase() 函数进行添加。如果open为true（默认值），并且数据库连接尚未打开，则现在打开它。如果未指定连接名参数，则使用默认连接。如果连接名不存在数据库列表中，那么将会返回一个非法的连接。

\begin{notice}
这个函数是 线程安全的
\end{notice}

\begin{seeAlso}
 isOpen() 和 线程和SQL模块。
\end{seeAlso}

QString QSqlDatabase::databaseName() const

返回连接的连接数据库名称，当然它也可能是空的。

\begin{notice}
这个数据库名不是连接名。
\end{notice}

\begin{seeAlso}
setDatabaseName()。
\end{seeAlso}

QSqlDriver *QSqlDatabase::driver() const

返回被使用的数据库连接的所使用的数据库驱动。

\begin{seeAlso}
addDatabase() 和 drivers()
\end{seeAlso}

QString QSqlDatabase::driverName() const

返回连接的驱动名称

\begin{seeAlso}
addDatabase() 和 driver()
\end{seeAlso}

[static] QStringList QSqlDatabase::drivers()

返回一个可使用的数据库驱动列表 

\begin{seeAlso}
registerSqlDriver()。
\end{seeAlso}

QSqlQuery QSqlDatabase::exec(const QString \emph{\&query} = QString()) const


在这个数据库里执行 SQL 表达式和 返回一个 QSqhttps://doc.qt.io/qt-5/qsqlquery.html 对象。
使用 lastError() 来获取错误的信息。

如果查询为空，则返回一个空的、无效的查询。并且 lastError()。

\begin{seeAlso}
QSqlQuery 和 lastError()。
\end{seeAlso}

QString QSqlDatabase::hostName() const


返回连接的主机名；它有可能为空。

\begin{seeAlso}
 setHostName()。
\end{seeAlso}


[static] bool QSqlDatabase::isDriverAvailable(const QString \emph{\&name})


如果调用一个叫 name 的驱动，是可以使用的，那么就返回 true；反之返回 false。

\begin{seeAlso}
drivers()。
\end{seeAlso}

bool QSqlDatabase::isOpen() const

如果当前数据库连接是打开的，那么就返回 true，否则返回 false。

bool QSqlDatabase::isOpenError() const


如果打开数据库的连接有错误，那么就返回 true，否则返回 false。可以调用 lastError() 函数去获取相关的错误信息。

bool QSqlDatabase::isValid() const


如果 QSqlDatabase() 有一个有效的驱动，那么就返回 true。

例子：

\begin{cppcode}
QSqlDatabase db;
qDebug() << db.isValid();    // 返回 false

db = QSqlDatabase::database("sales");
qDebug() << db.isValid();    // 如果 "sales" 连接存在，就返回 true

QSqlDatabase::removeDatabase("sales");
qDebug() << db.isValid();    // 返回 false
\end{cppcode}

\href{https://doc.qt.io/qt-5/qsqlerror.html}{QSqlError} QSqlDatabase::lastError() const

返回这个数据库出现的最新错误信息。

使用 QSqlQuery::lastError() 函数来获取一个单个查询上的错误。

\begin{seeAlso}
QSqlError and QSqlQuery::lastError()。
\end{seeAlso}


QSql::NumericalPrecisionPolicyQSqlDatabase::numericalPrecisionPolicy() const

返回数据库连接的当前默认精度策略。

qt4.6中引入了这个函数。

\begin{seeAlso}
QSql::NumericalPrecisionPolicy, setNumericalPrecisionPolicy()、
QSqlQuery::numericalPrecisionPolicy() 和 QSqlQuery::setNumericalPrecisionPolicy()。
\end{seeAlso}

bool QSqlDatabase::open()

使用当前连接值打开数据库连接。如果操作成功就返回 true; 反之返回 false。可以调用 lastError()来获取错误的信息。

\begin{seeAlso}
lastError()、 setDatabaseName()、setUserName()、
setPassword()、setHostName()、setPort()和 setConnectOptions()。
\end{seeAlso}

bool QSqlDatabase::open(const QString \emph{\&user}, const QString \emph{\&password})

这是一个重载函数。

使用所给的 username 和 password 两个参数，打开数据连接，如果成功就返回 true; 反之返回 false。使用 [lastError()]QSqlDatabase.md\#qsqlerror-qsqldatabaselasterror-const) 来获取错误的信息。

这个函数不存放所给的 password 参数，相反的它会把 password 参数直接传给驱动用于打连接，然后销毁这个参数。

\begin{seeAlso}
lastError()。
\end{seeAlso}

QString QSqlDatabase::password() const


返回连接的密码。如果没有使用setPassword() 函数进行密码的设置 并且 没有调用 open() 以及 没有使用密码，那么就返回空的字符串。


\begin{seeAlso}
setPassword()。
\end{seeAlso}

int QSqlDatabase::port() const


返回连接的端口号。如果端口号没有设置，那么这个值就是未定义的。

\begin{seeAlso}
setPort()。
\end{seeAlso}

QSqlIndex QSqlDatabase::primaryIndex(const QString \emph{\&tablename}) const


返回所给表格名的索引。如果索引不存在，那么就返回一个空的 QSqlIndex

\begin{notice}
如果表在创建时没有被引用，一些驱动程序（如 QPSQL 驱动程序）可能要求您以小写的形式传递表格名。
\end{notice}


查看关于 Qt SQL driver 文档的更多信息。

\begin{seeAlso}
tables() 和 record()。
\end{seeAlso}


QSqlRecord QSqlDatabase::record(const QString \emph{\&tablename}) const


返回一个QSqlRecord，其中填充了名为tablename的表（或视图）中所有字段的名称。
字段在记录中出现的顺序未定义。如果没有这样的表格（或者视图）存在，将会返回一个空的记录。

\begin{notice}
如果表在创建时没有被引用，一些驱动程序（如 QPSQL 驱动程序）可能要求您以小写的形式传递表格名。
\end{notice}


查看 Qt SQL driver 文档的更多信息。

[static] void QSqlDatabase::registerSqlDriver(const QString \emph{\&name}, QSqlDriverCreatorBase \emph{*creator})

这个函数在 SQL框架中注册一个名为 name 的新 SQL 驱动程序。这个是非常有用的，如果您有一个自定义的驱动，并且您并不想把它编译作为一个插件。

例如：

\begin{cppcode}
QSqlDatabase::registerSqlDriver("MYDRIVER", new QSqlDriverCreator<QSqlDriver>);
QVERIFY(QSqlDatabase::drivers().contains("MYDRIVER"));
QSqlDatabase db = QSqlDatabase::addDatabase("MYDRIVER");
QVERIFY(db.isValid());
\end{cppcode}

QSqlDatabase拥有 creator 指针的所有权，因此您不能自己删除它。

\begin{seeAlso}
drivers()。
\end{seeAlso}

[static] void QSqlDatabase::removeDatabase(const QString \emph{\&connectionName})

从数据库列表中，删除一个叫 connectionName 数据库连接。

\begin{warning}
不应在数据库连接上打开查询的情况下调用此函数，否则将发生资源泄漏。
\end{warning}

\clearpage

例子：

\begin{cppcode}
// 错误
QSqlDatabase db = QSqlDatabase::database("sales");
QSqlQuery query("SELECT NAME, DOB FROM EMPLOYEES", db);
QSqlDatabase::removeDatabase("sales"); // 将会输出警告
// “db”现在是一个悬而未决的无效数据库连接，
// “查询”包含无效的结果集
\end{cppcode}


正确的做法：

\begin{cppcode}
{
    QSqlDatabase db = QSqlDatabase::database("sales");
    QSqlQuery query("SELECT NAME, DOB FROM EMPLOYEES", db);
}
// “db”和“query”都被销毁，因为它们超出了范围
QSqlDatabase::removeDatabase("sales"); // 正确的
\end{cppcode}

如果要删除默认连接，这个连接可能是通过调用 addDatabase() 函数而创建的，但未指定连接名称，可以通过对database()返回的数据库调用connectionName() 来检索默认连接名称。

\begin{notice}
如果没有创建默认数据库，将返回一个无效的数据库。
\end{notice}

\begin{notice}
这个函数是线程安全的
\end{notice}

\begin{seeAlso}
database()，connectionName()，和 线程和SQL模块。
\end{seeAlso}

bool QSqlDatabase::rollback()


在数据库里回滚一个事务，如果驱动支持一个事务以及一个 transaction() 已经被启动。如果操作成功返回 true。否则返回 false。

\begin{notice}
对于某些数据库，如果存在使用数据库进行选择的活动查询，则回滚将失败并返回false。确保在执行回滚操作之前，查询是 非活动 的状态。
\end{notice}

调用 lastError() 操作获得错误的相关信息。

\begin{seeAlso}
QSqlQuery::isActive()，QSqlDriver::hasFeature() 和 commit()。
\end{seeAlso}

void QSqlDatabase::setConnectOptions(const QString \emph{\&options} = QString())

设置一组数据库的具体的可选项。它必须在打之这个连接之前执行这个操作，否则是无效的。
另一个可能的原因是调用 QSqlDatabase::setConnectOptions() 去关闭这个连接，并且调用 open() 再次关闭这个连接。

选项字符串的格式是以分号分隔的选项名称，或选项=值对的列表。这个选项依赖于所使用的客户端：

\begin{tabular}{|c|c|c|}
	\hline
    ODBC & MySQL & PostgreSQL \\
	\hline
    SQL\_ATTR\_ACCESS\_MODE & CLIENT\_COMPRESS	& connect\_timeout \\
    \hline
    SQL\_ATTR\_LOGIN\_TIMEOUT & CLIENT\_FOUND\_ROWS &	options \\
    \hline
    SQL\_ATTR\_CONNECTION\_TIMEOUT	& CLIENT\_IGNORE\_SPACE &	tty \\
    \hline
    SQL\_ATTR\_CURRENT\_CATALOG &	CLIENT\_ODBC &	requiressl \\
\hline
    SQL\_ATTR\_METADATA\_ID &	CLIENT\_NO\_SCHEMA&	service \\
\hline
    SQL\_ATTR\_PACKET\_SIZE&	CLIENT\_INTERACTIVE&\\	
\hline
    SQL\_ATTR\_TRACEFILE&	UNIX\_SOCKET&	\\
\hline
    SQL\_ATTR\_TRACE&	MYSQL\_OPT\_RECONNECT& \\	
\hline
    SQL\_ATTR\_CONNECTION\_POOLING	&MYSQL\_OPT\_CONNECT\_TIMEOUT& \\	
\hline
    SQL\_ATTR\_ODBC\_VERSION&	MYSQL\_OPT\_READ\_TIMEOUT&\\	
\hline
                         &MYSQL\_OPT\_WRITE\_TIMEOUT&	\\
\hline
                         &SSL\_KEY&	 \\
\hline
                         &SSL\_CERT&\\	
\hline
                         &SSL\_CA&	\\
\hline
                         &SSL\_CAPATH&\\
\hline
                         &SSL\_CIPHER&\\
	\hline
\end{tabular}

\begin{tabular}{|c|c|c|}
	\hline
	DB2	&OCI	&TDS \\ 
	\hline
	SQL\_ATTR\_ACCESS\_MODE & OCI\_ATTR\_PREFETCH\_ROWS	& 无 \\
	\hline
	SQL\_ATTR\_LOGIN\_TIMEOUT & OCI\_ATTR\_PREFETCH\_MEMORY& \\	
	\hline
\end{tabular}

\begin{tabular}{|c|c|}
	\hline
	\href{https://doc.qt.io/qt-5/qtsql-attribution-sqlite.html#sqlite}{SQLite} & Interbase \\ 
	\hline
	QSQLITE\_BUSY\_TIMEOUT & ISC\_DPB\_LC\_CTYPE \\ 
	\hline
	QSQLITE\_OPEN\_READONLY	& ISC\_DPB\_SQL\_ROLE\_NAME \\ 
	\hline
	QSQLITE\_OPEN\_URI&	\\ 
	\hline
	QSQLITE\_ENABLE\_SHARED\_CACHE	& \\
	\hline
	QSQLITE\_ENABLE\_REGEXP &  \\
	\hline
\end{tabular}

\clearpage

例子：

\begin{cppcode}
db.setConnectOptions("SSL_KEY=client-key.pem;SSL_CERT=client-cert.pem;SSL_CA=ca-cert.pem;CLIENT_IGNORE_SPACE=1"); // 使用安全套连字进行连接
if (!db.open()) {
	db.setConnectOptions(); // 清除连接的字符串
	// ...
}
// ...
// PostgreSQL 连接
db.setConnectOptions("requiressl=1"); // 确保 PostgreSQL 安全套接字连接
if (!db.open()) {
	db.setConnectOptions(); // 清除可选
	// ...
}
// ...
// ODBC 连接
db.setConnectOptions("SQL_ATTR_ACCESS_MODE=SQL_MODE_READ_ONLY;SQL_ATTR_TRACE=SQL_OPT_TRACE_ON"); // 设置 ODBC 连项
if (!db.open()) {
	db.setConnectOptions(); // 不要尝试去设置这个选项。
	// ...
}
}
\end{cppcode}

查阅这个客户端库文档，获得更多关于不同可选项的更多信息。

\begin{seeAlso}
connectOptions()。
\end{seeAlso}



void QSqlDatabase::setDatabaseName(const QString \&name)

通过所给的 name 参数来设置所连接的数据库名称。必须在打开连接之前设置数据库名称。 或者，可以调用close()函数关闭连接，设置数据库名称，然后再次调用open() 。

\begin{notice}
这个数据库名不是连接名。必须在创建连接对象时将连接名称传递给 addDatabase()。
\end{notice}


对于 QSQLITE 驱动，如果数据库名指定的名字不存在，然后它将会创建这个文件，除非您设置了 QSQLITE\_OPEN\_READONLY

此外，可以把 name 参数设置为 :memory:, 可以创建一个临时数据库，该数据库仅在应用程序的生命周期内可用。

对于 QOCI (Oracle) 驱动，这个数据库名是 TNS Service Name。

对于 QODBC 驱动程序，名称可以是DSN，DSN文件名（在这种情况下，文件扩展名必须为.DSN）或者是一个连接字符串。

例如，Microsoft Access 可以使用下面的连接方式来直接打开 .mdb 文件，而不是在 ODBC 管理工具里创建一个 DSN 对象：

\clearpage

\begin{cppcode}
// ...
QSqlDatabase db = QSqlDatabase::addDatabase("QODBC");
db.setDatabaseName("DRIVER={Microsoft Access Driver (*.mdb, *.accdb)};
FIL={MS Access};DBQ=myaccessfile.mdb");
if (db.open()) {
	// 成功!
}
// ...
\end{cppcode}

这个没有默认的值

\begin{seeAlso}
databaseName()、setUserName()、 setPassword()、 setHostName()、setPort()、setConnectOptions() 和 open()。
\end{seeAlso}


void QSqlDatabase::setHostName(const QString \emph{\&host})

通过 host 参数来设置连接的主机名。为了生效，必须在打开连接之前，设置主机名。或者，可以调用close()关闭连接，然后设置主机名，再次调用open()函数。

这个没有默认值。

\begin{seeAlso}
hostName()， setUserName(), setPassword()，setDatabaseName()，setPort()， setConnectOptions() 和 open()。
\end{seeAlso}


void QSqlDatabase::setNumericalPrecisionPolicy(QSql::NumericalPrecisionPolicy precisionPolicy)


设置在此数据库连接上创建的查询使用的默认数值精度策略。

\begin{notice}
驱动程序不支持以低精度获取数值，将忽略精度策略。您可以使用 QSqlDriver::hasFeature()来查找一个驱动是否支持这个功能。
\end{notice}

\begin{notice}
通过 precisionPolicy 来设置这个默认的精度策略，将不会响影任何当前的活动查询。
\end{notice}

qt4.6中引入了这个函数。


\begin{seeAlso}
QSql::NumericalPrecisionPolicy，
numericalPrecisionPolicy()，QSqlQuery::setNumericalPrecisionPolicy 和 QSqlQuery::numericalPrecisionPolicy。
\end{seeAlso}



void QSqlDatabase::setPassword(const QString \&password)
通过 password 参数来设置连接的密码。为了生效，必须在打开连接之前来设置密码。或者，您可以调用close()关闭连接，然后设置密码，再次调用open()函数。

这个没有默认值。

\begin{warning}
这个函数以明文的形式把密码存放到qt里。 将密码作为参数来避免这个行为，然后使用 open()进行调用。
\end{warning}

\begin{seeAlso}
password()，setUserName()，setDatabaseName()，setHostName(),
setPort(), setConnectOptions()和 open()。
\end{seeAlso}

void QSqlDatabase::setPort(int port)

通过port参数设置连接的端口号。为了生效，您必须在打开连接之前，进行端口号的设置。或者，您可以调用close()关闭连接，然后设置端口号，再次调用open()函数

这个没有默认的值。

\begin{seeAlso}
port(), setUserName()， setPassword(),
setHostName()，setDatabaseName(), setConnectOptions() 和 open()。
\end{seeAlso}


void QSqlDatabase::setUserName(const QString \&name)

通过 name 参数来设置连接的用户名。为了生效，必须在打开连接之前设置用户名。或者，您可以调用 close()函数来关闭连接，设置用户，然后再次调用 open()

这个没有默认值。

\begin{seeAlso}
userName()，setDatabaseName()，setPassword()，
setHostName()，setPort()，setConnectOptions() 和 open()。
\end{seeAlso}

QStringList QSqlDatabase::tables(QSql::TableType type = QSql::Tables) const

返回由 parameter type 参数 指定的数据库的表格、系统表和视图的列表。

\begin{seeAlso}
primaryIndex() 和 record()。
\end{seeAlso}

bool QSqlDatabase::transaction()

如果驱动程序支持事务，则在数据库上开始事务。如果操作成功的话，返回 true, 否则返回 false。

\begin{seeAlso}
QSqlDriver::hasFeature()， commit() 和 rollback()。
\end{seeAlso}

QString QSqlDatabase::userName() const

返回连接的用户名; 它也许为空。

\begin{seeAlso}
setUserName()。
\end{seeAlso}

